/*
 *  Copyright 2001-2004 The Apache Software Foundation
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 */
package ar.uba.fi.posgrado.common.aop;

import java.io.IOException;
import java.io.PrintWriter;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;

/**
 * Aspecto (AOP) para cargar en un archivo la secuencia
 * de flujo de la aplicacion para generar diagramas de secuencia.<br>
 * 
 * @author nicolas.gonzalez
 */
@Aspect
public class AroundAspect {

    private String filename;

    private static PrintWriter writer;



    /**
     * Obtiene el nombre del archivo al cual se genera la salida
     * 
     * @return nombre del archivo
     */
    public String getFilename() {
        return filename;
    }



    /**
     * Setea el nombre del archivo al cual se genera la salida
     * 
     * @param filename
     *            nombre del archivo a setear con path
     */
    public void setFilename(String filename) {
        this.filename = filename;
    }



    private String printClassName(String fullName) {
        return fullName.substring(fullName.lastIndexOf(".") + 1);
    }



    /**
     * Metodo utilizado para tracear un la invocacion a un metodo
     * 
     * @param pjp
     *            punto de interrupcion para el aspecto
     * @return resultado de la invocacion al metodo original
     * @throws Throwable
     *             en caso de ocurrir algun error
     */
    @Around("execution(* ar.uba.fi.posgrado.common.service..*.*(..))")
    public Object traceMethod(ProceedingJoinPoint pjp) throws Throwable {

        writer.println(printClassName(pjp.getSignature().getDeclaringTypeName()) + "."
                + pjp.getSignature().toShortString() + " -> "
                + printClassName(pjp.getSignature().toLongString().split(" ")[2]) + " {");

        Object value = pjp.proceed();

        writer.println("}");

        return value;
    }



    /**
     * Inicializa el acceso al archivo de salida
     * 
     */
    public void initFile() {
        try {
            writer = new PrintWriter(filename);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }



    /**
     * Cierra el archivo utilizado para trace
     * 
     */
    public void finalizeFile() {
        writer.flush();
        writer.close();
    }
    
    
}
